


let home_folder = Unix.getenv "HOME"
let digest_db_folder = Filename.concat home_folder ".mldupes"
let digest_db_file_name = "digests.db"
let digest_db_folder_perm = 0o640
let digest_db_path = Filename.concat digest_db_folder digest_db_file_name

let test = "badabou\n"

let approximate_db_length = 100

let rec create_digest_db_file = fun () ->
  match (Sys.file_exists digest_db_folder, Sys.file_exists digest_db_path) with
      true, true -> ()
    | true, false -> 
        let digest_db_file_out = open_out digest_db_path in
        output_string digest_db_file_out "";
        close_out digest_db_file_out;
    | false, _ ->
	let _ = Unix.mkdir digest_db_folder digest_db_folder_perm in
	create_digest_db_file ()
    
let _ = create_digest_db_file ()

let digest_db =
  let digest_db_file_in = open_in digest_db_path in
  let rec loop = fun i ->
    try
      let _ = input_line digest_db_file_in in
      loop (i+1)
    with End_of_file -> i in
  let length = max (loop 0) approximate_db_length in
(*   let _ = print_endline ("Digest database creation with "^(string_of_int length)^" entries") in *)
  Hashtbl.create length

(*let _ = Hashtbl.add digest_db "/home/jeremy/examples.desktop" ("1288258610.", "e7444acd4d538ede466c6d6cb932c5ec")*)

let parse_db_line = fun s ->
  let sep = ' ' in
  let index = String.index_from s 0 sep in
  let mtime = String.sub s 0 index in
  let md5sum = Tools.rest_of_string s (index + 1) in
  (mtime, md5sum)
  
let load_digest_db = fun () ->
 let digest_db_file_in = open_in digest_db_path in
 let rec loop = fun () ->
   try 
     try
       let path = input_line digest_db_file_in in
       let (mtime, md5sum) = parse_db_line (input_line digest_db_file_in) in
       let _ = Hashtbl.add digest_db path (mtime, md5sum) in 
       loop ()
     with Not_found -> loop ()
   with End_of_file -> close_in digest_db_file_in
  in loop ()

let store_digest_db = fun () ->
  let _ = Unix.unlink digest_db_path in
  let _ = create_digest_db_file () in
  let digest_db_file_out = open_out digest_db_path in
  let store_path = fun path (mtime, md5sum) ->
    output_string digest_db_file_out (path^"\n"^mtime^" "^md5sum^"\n") in
  let _ = Hashtbl.iter store_path digest_db in
  close_out digest_db_file_out
    
let digest_lookup = fun info path ->
  let given_mtime = string_of_float info.Unix.st_mtime in
  try
    let (mtime, md5sum) = Hashtbl.find digest_db path in
    match String.compare mtime given_mtime with
        0 -> md5sum
      | _ -> let new_md5sum = Digest.to_hex (Digest.file path) in
             let _ = Hashtbl.replace digest_db path (mtime, new_md5sum) in
(*              let _ = print_endline (path^" updated in database") in *)
             new_md5sum
  with Not_found ->
    let md5sum = Digest.to_hex (Digest.file path) in
    let _ = Hashtbl.add digest_db path (given_mtime, md5sum) in
(*     let _ = print_endline (path^" added to database") in *)
    md5sum
